﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace robot
{
    class Robot
    {
        //Liste d'objet portée par le robot
        private List<Objet> objets;
        //Salle actuelle
        private Salle location;
        //Terrain
        private Terrain terrain;

        public Robot(Terrain terrain)
        {
            this.terrain = terrain;

            objets = new List<Objet>();
            //Objets de base contenu par le robot
            objets.Add(new Table(30, 40));
            objets.Add(new Chaise(4, "verte"));
            objets.Add(new Bouteille(30, "Ruhm"));
        }

        /**
         * Affiche l'inventaire du robot
         */
        public string AfficheContenu()
        {
            string str = "";
            int num = 0;
            foreach (Objet objet in objets)
            {
                str += num.ToString() + ") ";
                str += objet.ToString();
                str += "\n";
                num++;
            }
            return str;
        }

        /**
         * Récupère tous les objets de la salle actuelle
         */
        private void prendreToutObjet()
        {
            foreach (Objet o in location.Objets)
            {
                objets.Add(o);
            }
            location.Clear();                       
        }

        /**
         * Dépose tous les objets de l'inventaire dans la salle actuelle 
         */
        private void deposerToutObjet()
        {
            foreach (Objet o in objets)
            {
                location.AjouterObjet(o);
            }
            objets.Clear();
        }

        /**
         * Récupère un seul objet de la salle choisit par l'utilisateur
         */
        private void prendreObjet(int num)
        {
            objets.Add(location.Retirer(num));
        }

        /**
         * Dépose un seul objet de son inventaire dans la salle, choisit par l'utilisateur
         */
        private void deposerObjet(int num)
        {
           location.AjouterObjet(objets[num]);
           objets.RemoveAt(num);    
        }
    
        /**
         * Change la salle actuelle
         */
        public void EntrerSalle(Salle s)
        {
            location = s;  
            Console.WriteLine("Vous venez d'entrer dans une nouvelle salle bien accueillante.\n");
        }

        /**
         * Gestion des entréesde l'utilisateur
         */
        public void Evenement()
        {
            int menu;
            do
            {
                //Ecriture du menu de jeu
                Console.WriteLine("\n"+ location +
                    "\nQue souhaitez vous faire maintenant ?\n\n"
                    + "1) Examiner la salle\n2) Prendre un objet\n3) Déposer un objet\n4) Sortir de la salle\n5) Quitter");
                //récupération d'une entrée de l'utilisateur
                menu = LireEntier();
                Console.WriteLine();
                
                switch ( menu )
                {
                    case 1:
                        //Affiche la description de la salle
                        Console.WriteLine(location.Description());
                        break;
                    case 2:
                        //Affiche le menu de récupération d'objets
                        MenuPrendre(location);
                        break;
                    case 3:
                        //Affiche le menu de dépot d'objets
                        MenuDeposer(location);
                        break;
                    case 4:
                        //Affiche le menu de direction
                        MenuSalle(location);
                        break;
                }
            } while ( menu != 5);
        }

        /**
         * Menu de récupération d'objets
         */
        private void MenuPrendre(Salle s)
        {
            int menu;
            int nbObjet = s.Objets.Count();
            Console.WriteLine("Selectionner votre objet : \n{0}{1}) Tout prendre\n{2}) Ne rien prendre\n ", s.ListerContenu(), nbObjet, nbObjet + 1);
            do
            {
                menu = LireEntier();
            } while (menu > nbObjet+2 || menu < 0);
            //Le robot récupère l'objet sélectionné
            if (menu < nbObjet)
                prendreObjet(menu);
            //Le robot récupère tous les objets de la salle
            else if (menu == nbObjet)
                prendreToutObjet();
            Console.WriteLine(AfficheContenu());
        }

        /**
         * Menu de dépot d'objets
         */
        private void MenuDeposer(Salle s)
        {
            int menu;
            int nbObjet = objets.Count();
            Console.WriteLine("Selectionner votre objet : \n{0}{1}) Tout déposer\n{2}) Ne rien déposer\n ", AfficheContenu(), nbObjet, nbObjet + 1);
            do
            {
                menu = LireEntier();
            } while (menu > nbObjet + 2 || menu < 0);
            //Le robot dépose l'objet sélectionné
            if (menu < nbObjet)
                deposerObjet(menu);
            //Le robot dépose tous les objets dans la salle
            else if (menu == nbObjet)
                deposerToutObjet();
            Console.WriteLine(AfficheContenu());
        }

        /**
         * Choisi la direction du robot
         */
        public void MenuSalle(Salle s)
        {
            String direction = "";
            Salle voisine;
            Console.WriteLine("Salles voisines : " + s.SallesVoisines() +
                "\nOu voulez-vous aller ? ("+ Terrain.ListeDirection() + " quit) : ");
            direction = LireDirection();
            voisine = s.Voisine(direction);
            if (voisine != null)
                EntrerSalle(voisine);
            else
            {
                Console.WriteLine("Vous heurtez violamment le mur là où une porte manque");
            }

        }

        /**
         * Liste le contenu de l'inventaire
         */
        public String ListerContenu()
        {
            String s = "";
            int i = 0;
            foreach (Objet o in objets)
            {
                s += i + ") " + o.ToString() + "\n";
            }
            return s;
        }

        /**
         * Vérifie la validité de l'entrée de l'utilisateur pour un entier
         */
        static private int LireEntier()
        {
            int result = 0;
            bool recommence = true;
            while (recommence)
            {
                recommence = false;
                try
                {
                    result = Int16.Parse(Console.ReadLine());
                }
                catch (System.FormatException)    // si l'utilisateur a entré une erreur
                {
                    recommence = true;
                }
            }
            return result;
        }


        /**
         * Vérifie la validité de l'entrée de l'utilisateur pour une string de direction
         */
        static String LireDirection()
        {
            String direction = "";
            do
            {
                direction = Console.ReadLine().ToLower();

            } while (! Terrain.DirectionValide(direction) && !direction.Equals("quit"));
            return direction;
        }
    }
}
